package cn.modfun.common.loader;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @author LinCH
 *
 */
public class DiskClassLoader extends ClassLoader {

	private List<Class<?>> classes = new ArrayList<Class<?>>();
	
	/**
	 * 单纯的加载jar中的所有类文件
	 * @param jarFolderPath
	 */
	public void loadJars(String jarFolderPath){
		/* 获取指定目录下的jar文件 */
		File[] files = new File(jarFolderPath).listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return new File(dir, name).isFile() && name.endsWith(".jar");
            }
        });
		if(files!=null){
			/* 加载类 */
			Method method;
			try {
				method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
				boolean accessible = method.isAccessible();     // 获取方法的访问权限  
			    try {  
			        if (accessible == false) {  
			            method.setAccessible(true);     // 设置方法的访问权限  
			        }  
			        // 获取系统类加载器  
			        URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();  
			        for (File file : files) {  
			            URL url;
						try {
							url = file.toURI().toURL();
							method.invoke(classLoader, url);
						} catch (MalformedURLException e1) {
							e1.printStackTrace();
						} catch (IllegalAccessException e) {
							e.printStackTrace();
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						} catch (InvocationTargetException e) {
							e.printStackTrace();
						}  
			        }  
			    } finally {  
			        method.setAccessible(accessible);  
			    }
			} catch (NoSuchMethodException e1) {
				e1.printStackTrace();
			} catch (SecurityException e1) {
				e1.printStackTrace();
			}  
		    /* 把匹配的类加入至对象中 */
			for(File file : files){
		    	JarFile jar;
				try {
					jar = new JarFile(file.getAbsolutePath());
					Enumeration<JarEntry> entries = jar.entries();
					while (entries.hasMoreElements()) {
						JarEntry jarEntry = entries.nextElement();
						String entryName = jarEntry.getName();
						if (!jarEntry.isDirectory() && entryName.endsWith(".class")) {
							String className = entryName.replace('/', '.');
							className = className.substring(0, className.length()-6);
							try {
								classes.add(Class.forName(className));
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
					jar.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
		    }
		}
	}
	/**
	 * 获得带有匹配注解的类文件
	 * @param jarFolderPath
	 * @param annotation
	 * @return
	 */
	public List<Class<?>> getClassesByAnnotationForJars(String jarFolderPath,Class<?> annotation){
		List<Class<?>> _classes = new ArrayList<Class<?>>();
		try {
			loadJars(jarFolderPath);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(classes!=null && classes.size() > 0){
			for(Class cls : classes){
				if(cls.getAnnotation(annotation)!=null){
					_classes.add(cls);
				}
			}
		}
		return _classes;
	}
}
